﻿var __extends = this.__extends || function (d, b) {
    for (var p in b) if (b.hasOwnProperty(p)) d[p] = b[p];
    function __() { this.constructor = d; }
    __.prototype = b.prototype;
    d.prototype = new __();
};
var anonymousProperty = "anonymous";

var DynamicMvvm = (function () {
    function DynamicMvvm() {
        this.MarkupExtensions = {};
        this.DependencyProperties = {};
    }
    DynamicMvvm.prototype.bindData = function (model, element) {
        var elementTobind = element == null ? document.getElementsByTagName("body")[0] : element;
        elementTobind['dataContext'] = model;
    };

    DynamicMvvm.prototype.bindDataInternal = function (model, element) {
        if (element == null)
            return;

        this.applyBindingToControl(element, model);
        for (var i in element.children) {
            var childElement = element.children[i];
            this.bindDataInternal(model, childElement);
        }
    };

    DynamicMvvm.prototype.applyBindingToControl = function (element, model) {
        if (element == null || element.dataset == null)
            return;

        for (var key in this.DependencyProperties) {
            var dpDataset = element.dataset[key];

            if (dpDataset != null) {
                var dpValue = this.DependencyProperties[key];
                var markupExt = this.getMarkupExtensionObject(dpDataset);
                markupExt.Element = element;
                dpValue.init(element, model, markupExt);
            }
        }
    };

    DynamicMvvm.prototype.getMarkupExtensionObject = function (markupString) {
        if (markupString != null) {
            var bindingPattern = new RegExp("{(.*)}");

            var extractedString = bindingPattern.exec(markupString)[1];
            var spaceAt = extractedString.indexOf(' ', 0);
            var markupExtension = extractedString.substr(0, spaceAt);

            var markupExtensionObj = Object.create(this.MarkupExtensions[markupExtension]);
            markupExtensionObj.constructor.apply();

            //build new object
            //var markupExtFunction = new Function("markupExtension", "self = this; self.binding = markupExtension;");
            //var markupExtensionObj = new Object(); //new markupExtFunction(markupExtension);
            markupExtensionObj['markupExtension'] = markupExtension;

            //extract parameter string array
            var extsParams = extractedString.substr(spaceAt + 1).split(',');

            for (var i = 0; i < extsParams.length; i++) {
                var splittedParams = extsParams[i].split(',');

                if (splittedParams.length == 1) {
                    markupExtensionObj[anonymousProperty + '_' + i] = splittedParams[0];
                } else {
                    markupExtensionObj[splittedParams[0]] = splittedParams[1];
                }
            }
            return markupExtensionObj;
        }
        return null;
    };
    return DynamicMvvm;
})();

var PropertyMetadata = (function () {
    function PropertyMetadata() {
    }
    return PropertyMetadata;
})();

var dynamicMvvm = new DynamicMvvm();

var DependencyProperty = (function () {
    function DependencyProperty() {
    }
    DependencyProperty.prototype.register = function (name) {
    };
    DependencyProperty.prototype.init = function (element, model, markup) {
    };
    DependencyProperty.prototype.getMetadata = function (forType) {
        return null;
    };

    DependencyProperty.register = function (name, dpType) {
        dpType.register(name);
        dynamicMvvm.DependencyProperties[name] = dpType;
    };
    return DependencyProperty;
})();

var dataContextDependencyProperty = (function () {
    function dataContextDependencyProperty() {
    }
    dataContextDependencyProperty.prototype.register = function (name) {
        Object.defineProperty(Element.prototype, "dataContext", {
            get: function () {
                var dataContext = this._dataContext;
                if (dataContext === undefined && this.parentElement !== undefined) {
                    return this.parentElement.dataContext;
                }
                return dataContext;
            },
            set: function (value) {
                this._dataContext = value;
                dynamicMvvm.bindDataInternal(value, this);
            }
        });
    };

    dataContextDependencyProperty.prototype.init = function (element, model, markup) {
        element["dataContext"] = markup.provideValue();
    };

    dataContextDependencyProperty.prototype.getMetadata = function (forType) {
        return new PropertyMetadata();
    };
    return dataContextDependencyProperty;
})();

DependencyProperty.register("dataContext", new dataContextDependencyProperty());

var valueDependencyProperty = (function () {
    function valueDependencyProperty() {
    }
    valueDependencyProperty.prototype.register = function (name) {
        //HTMLInputElement.prototype.onblur
        //Element.prototype.addEventListener(
    };

    valueDependencyProperty.prototype.init = function (element, model, markup) {
        try  {
            var inputElement = element;

            inputElement.addEventListener("blur", function (e) {
                var inputElement = e.srcElement;
            }, false);

            inputElement.value = markup.provideValue();
        } catch (e) {
        }
    };

    valueDependencyProperty.prototype.getMetadata = function (forType) {
        return new PropertyMetadata();
    };
    return valueDependencyProperty;
})();

DependencyProperty.register("value", new valueDependencyProperty());

var MarkupExtension = (function () {
    function MarkupExtension() {
    }
    MarkupExtension.prototype.provideValue = function () {
        return null;
    };

    MarkupExtension.register = function (name, markupExtension) {
        dynamicMvvm.MarkupExtensions[name] = markupExtension;
    };
    return MarkupExtension;
})();

var BindingMarkupExtension = (function (_super) {
    __extends(BindingMarkupExtension, _super);
    function BindingMarkupExtension() {
        _super.apply(this, arguments);
    }
    BindingMarkupExtension.prototype.provideValue = function () {
        var path = this.GetPath();
        var source = this.GetDataSource();

        return source[path];
    };

    BindingMarkupExtension.prototype.GetDataSource = function () {
        if (this["dataSource"] == undefined) {
            return this.Element["dataContext"];
        }
        return this["dataSource"];
    };

    BindingMarkupExtension.prototype.GetPath = function () {
        if (this["path"] == undefined) {
            return this[anonymousProperty + "_0"];
        }
        return this["path"];
    };
    return BindingMarkupExtension;
})(MarkupExtension);

MarkupExtension.register("Binding", BindingMarkupExtension.prototype);

HTMLElement.prototype.setValue = function (property, value) {
    var htmlElement = this;
};

HTMLElement.prototype.getValue = function (property) {
    //this
};

HTMLElement.prototype.setdataContext = function (value) {
    var htmlElement = this;
    htmlElement["dataContext"] = value;
};
